package Character;


import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;


import com.ydDev.charateranimation.R;
import com.ydDev.charateranimation.R.drawable;

import android.graphics.Canvas;
import GameTools.ydMath;
import GameTools.ydPoint;

public class Character_Skeleton {

	final static int TOLERANCE = 20;
	final static double RADIO = 2;
	final static int HEAD_SIZE = 15;
	final static int NECK_SIZE = 10;
	final static int TORSO_SIZE = 100;
	final static int ARM_SIZE = 50;
	final static int FOREARM_SIZE = 50;
	final static int THIGH_SIZE = 60;
	final static int CALF_SIZE = 60;

	final static int HEAD_WIDTH = 40;
	final static int HEAD_HEIGHT = 45;
	final static int TORSO_WIDTH = 105;
	final static int TORSO_HEIGHT = 161;
	final static int BICEP_WIDTH = 84;
	final static int BICEP_HEIGHT = 28;
	final static int FOREARM_WIDTH = 54;
	final static int FOREARM_HEIGHT = 24;
	final static int THIGH_WIDTH = 41;
	final static int THIGH_HEIGHT = 96;
	final static int LEG_WIDTH = 31;
	final static int LEG_HEIGHT = 105;

	ArrayList<Boolean> showParts = new ArrayList<Boolean>();
	int jointSelected=0;

	Head head;

	Arm leftA, rightA;

	Leg leftL, rightL;

	Torso torso;

	BodyPart gndThigh, actThigh, gndCalf, actCalf;

	Boolean isRunning;

	double angulerVelocity;

	public Character_Skeleton(ydPoint startPostion) {

		head = new Head(new ydPoint(240, 20));

		torso = new Torso(head.head.j2);

		leftA = new Arm(torso.torso.j1);
		rightA = new Arm(torso.torso.j1);


		rightL = new Leg(torso.torso.j2);
		leftL = new Leg(torso.torso.j2);
		
		readjust();
		angulerVelocity = 0.05;

		isRunning = false;

	}
	
	public void readjust(){
		ydPoint shift = new ydPoint(head.head.j2.x - torso.torso.limb.p1.x,
				head.head.j2.y - torso.torso.limb.p1.y);
		
		torso.deltaMove(shift);
		
		shift.x = torso.torso.j1.x - rightA.arm.j1.x;
		shift.y = torso.torso.j1.y - rightA.arm.j1.y;
		
		rightA.deltaMove(shift);
		leftA.deltaMove(shift);
		
		shift.x = torso.torso.j2.x - rightL.thigh.j1.x;
		shift.y = torso.torso.j2.y - rightL.thigh.j1.y;

		rightL.deltaMove(shift);
		leftL.deltaMove(shift);
		
		shift.x = torso.torso.j1.x - head.head.j2.x;
		shift.y = torso.torso.limb.p1.y - head.head.j2.y;		
		
		rightA.readjust();
		leftA.readjust();
		
		rightL.readjust();
		leftL.readjust();
	}

	public void draw(Canvas canvas) {

		if (showParts.get(0))
			head.draw(canvas);
		if (showParts.get(5))
			leftL.draw(canvas);
		if (showParts.get(3))
			leftA.draw(canvas);
		if (showParts.get(1))
			torso.draw(canvas);
		if (showParts.get(4))
			rightL.draw(canvas);
		if (showParts.get(2))
			rightA.draw(canvas);
	}

	/*
	 * public void run(){
	 * 
	 * if(!isRunning){ //if(LeftCalf.limb.p2.x>RightCalf.limb.p2.x){
	 * gndThigh=LeftThigh; gndCalf=LeftCalf;
	 * 
	 * actThigh=RightThigh; actCalf=RightCalf;
	 * 
	 * angulerVelocity=0.5; // } // else{ gndThigh=RightThigh;
	 * gndCalf=RightCalf;
	 * 
	 * actThigh=LeftThigh; actCalf=LeftCalf; // }
	 * 
	 * 
	 * setRunSpeeds(0); isRunning=true; }
	 * 
	 * 
	 * 
	 * if(angulerVelocity<0.5) angulerVelocity+=0.01;
	 * 
	 * //runActiveLeg(); runActiveLeg(actThigh,actCalf);
	 * runGndLeg(gndThigh,gndCalf); //runActiveLeg(gndThigh,gndCalf);
	 * 
	 * }
	 */

	public void stopRunning() {
		gndThigh.angularVelocity = 0;
		gndCalf.angularVelocity = 0;

		actThigh.angularVelocity = 0;
		actCalf.angularVelocity = 0;
	}

	public void setRunSpeeds(int i) {

		if (i == 0) {
			gndThigh.angularVelocity = -ydMath
					.degreesToRads((float) angulerVelocity);
			gndCalf.angularVelocity = ydMath
					.degreesToRads((float) (angulerVelocity * 2));

			actThigh.angularVelocity = -ydMath
					.degreesToRads((float) angulerVelocity * 2);
			actCalf.angularVelocity = ydMath
					.degreesToRads((float) (angulerVelocity * 7));
		} else {
			gndThigh.angularVelocity = -ydMath
					.degreesToRads((float) angulerVelocity * 2);
			gndCalf.angularVelocity = ydMath
					.degreesToRads((float) (angulerVelocity * 4));

			actThigh.angularVelocity = -ydMath
					.degreesToRads((float) angulerVelocity * 2);
			actCalf.angularVelocity = ydMath
					.degreesToRads((float) (angulerVelocity * 7));
		}
	}

	/*
	 * public void runActiveLeg(){ ydPoint pivot=actThigh.limb.p1;
	 * 
	 * 
	 * if(actThigh.limb.angle>180){ actThigh.angularVelocity*=-1;
	 * //actThigh.limb.rotate(pivot, ydMath.degreesToRads((float)
	 * (180-actThigh.limb.angle))); } else if(actThigh.limb.angle<0){
	 * actThigh.angularVelocity*=-1; //actThigh.limb.rotate(pivot,
	 * ydMath.degreesToRads((float) (-actThigh.limb.angle))); }
	 * 
	 * if(actCalf.limb.angle>180){ actCalf.angularVelocity*=-1;
	 * //actCalf.limb.rotate(pivot, ydMath.degreesToRads((float)
	 * (180-actCalf.limb.angle))); } else if(actCalf.limb.angle<0){
	 * actCalf.angularVelocity*=-1; //actCalf.limb.rotate(pivot,
	 * ydMath.degreesToRads((float) (-actCalf.limb.angle))); }
	 * 
	 * if(actCalf.limb.angle>180 || actCalf.limb.angle<0)
	 * actCalf.angularVelocity*=-1;
	 * 
	 * actThigh.limb.rotate(pivot,actThigh.angularVelocity);
	 * 
	 * actCalf.limb.rotate(pivot, actCalf.angularVelocity);
	 * actCalf.limb.move(actThigh.limb.p2); }
	 */

	public void runActiveLeg(BodyPart b1, BodyPart b2) {
		ydPoint pivot = b1.limb.p1;

		/*
		 * if(b1.limb.angle>135 || b1.limb.angle<45) b1.angularVelocity*=-1;
		 */

		if (b2.limb.angle > 135 || b2.limb.angle < 45
				|| b1.limb.angle > b2.limb.angle) {
			// b2.limb.rotate(pivot, ydMath.degreesToRads((float)
			// (180-b2.limb.angle)));
			b2.angularVelocity *= -1;
		}

		b1.limb.rotate(pivot, b1.angularVelocity);

		b2.limb.rotate(pivot, b2.angularVelocity);
		b2.limb.moveTo(b1.limb.p2);
	}

	public void runGndLeg(BodyPart b1, BodyPart b2) {
		ydPoint pivot = b2.limb.p2;

		/*
		 * if(b1.limb.angle>135 || b1.limb.angle<45) b1.angularVelocity*=-1;
		 * 
		 * if(b2.limb.angle>135 || b2.limb.angle<45 ||
		 * b1.limb.angle>b2.limb.angle) b2.angularVelocity*=-1;
		 */

		b1.limb.rotate(b1.limb.p2, -b1.angularVelocity);

		b2.limb.rotate(pivot, b2.angularVelocity);
		// b2.limb.move(b1.limb.p2);

		// b2.limb.move(new ydPoint(300, 530),0);

		b1.limb.moveTo(b2.limb.p1, 0);
		// Torso.limb.move(b1.limb.p1, 0);
		actThigh.limb.moveTo(b1.limb.p1);
		actCalf.limb.moveTo(actThigh.limb.p2);

		if (b2.limb.angle > 135) {
			/*
			 * actThigh.limb.rotate(pivot, ydMath.degreesToRads((float)
			 * -(45-actThigh.limb.angle))); actCalf.limb.rotate(pivot,
			 * ydMath.degreesToRads((float) -(45-actCalf.limb.angle)));
			 * 
			 * gndThigh.limb.rotate(pivot, ydMath.degreesToRads((float)
			 * -(112.5-gndThigh.limb.angle))); gndCalf.limb.rotate(pivot,
			 * ydMath.degreesToRads((float) -(135-gndCalf.limb.angle)));
			 */

			BodyPart tmp1, tmp2;

			tmp1 = actCalf;
			actCalf = gndCalf;
			gndCalf = tmp1;

			tmp1 = actThigh;
			actThigh = gndThigh;
			gndThigh = tmp1;

			/*
			 * BodyPart.swap(actCalf, gndCalf); BodyPart.swap(actThigh,
			 * gndThigh);
			 */

			setRunSpeeds(1);

			return;
		}
	}

	public void rotatePart() {
		/*
		 * rightA.forearm.rotate(-0.01); leftA.forearm.rotate(0.1);
		 * 
		 * rightA.rotateArm(-0.05, 0); rightA.rotateArm(-0.01, 1);
		 * 
		 * rightL.rotateArm(0.005, 0); rightL.rotateArm(0.01, 1);
		 */

		rightL.calf.rotateTo(Math.PI);
	}

	public void pointTo(int selectedPart, ydPoint clickedAt) {

		switch (selectedPart) {
		case 0:
			head.moveTo(clickedAt);
		case 1:
			torso.pointTo(clickedAt, jointSelected);
			break;	
		case 2:
			rightA.pointTo(clickedAt, jointSelected);
			break;
		case 3:
			leftA.pointTo(clickedAt, jointSelected);
			break;
		case 4:
			rightL.pointTo(clickedAt, jointSelected);
			break;
		case 5:
			leftL.pointTo(clickedAt, jointSelected);
			break;
		}
		
		readjust();

	}

	public void showParts(ArrayList<Boolean> showParts, int jointSelected) {
		// TODO Auto-generated method stub
		for (int i = 0; i < showParts.size(); i++) {
			this.showParts.add(i, showParts.get(i));
		}
		
		this.jointSelected=jointSelected;
	}


	public JSONObject getJSONHead() {
		JSONObject json=new JSONObject();
		try {
			json.put("p1", head.head.limb.p1.toString());
			json.put("p2", head.head.limb.p2.toString());
			json.put("j1", head.head.j1.toString());
			json.put("j2", head.head.j2.toString());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return json;
	}
	
	public JSONObject getJSONTorso() {
		JSONObject json=new JSONObject();
		try {
			json.put("p1", torso.torso.limb.p1.toString());
			json.put("p2", torso.torso.limb.p2.toString());
			json.put("j1", torso.torso.j1.toString());
			json.put("j2", torso.torso.j2.toString());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return json;
	}
	
	public JSONObject getJSONArm(int i) {
		Arm tmp;
		if(i==0){
			tmp=rightA;
		}
		else{
			tmp=leftA;
		}
		JSONObject json=new JSONObject();
		try {
			json.put("arm", tmp.getJSONArm());
			json.put("forearm", tmp.getJSONForearm());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return json;
	}

	public void setAngularVelocities(ArrayList<Double> angularVelocities) {
		// TODO Auto-generated method stub
		head.head.angularVelocity=angularVelocities.get(0);
		
		torso.torso.angularVelocity=angularVelocities.get(1);
		
		rightA.arm.angularVelocity=angularVelocities.get(2);
		leftA.arm.angularVelocity=angularVelocities.get(3);
		
		rightL.thigh.angularVelocity=angularVelocities.get(4);
		leftL.thigh.angularVelocity=angularVelocities.get(5);
	}
	
	public void step(int direction){
		torso.rotate(direction);
		
		rightA.rotate(direction);
		leftA.rotate(direction);
		
		rightL.rotate(direction);
		leftL.rotate(direction);
	}

	public Object getJSONLeg(int i) {
		Leg tmp;
		if(i==0){
			tmp=rightL;
		}
		else{
			tmp=leftL;
		}
		JSONObject json=new JSONObject();
		try {
			json.put("thigh", tmp.getJSONThigh());
			json.put("calf", tmp.getJSONCalf());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return json;
	}

	public void loadPostion(JSONObject jsonObject) {
		
		head.loadPostion(jsonObject.optJSONObject("head"));
		torso.loadPostion(jsonObject.optJSONObject("torso"));
		rightA.loadPostion(jsonObject.optJSONObject("rightA"));
		leftA.loadPostion(jsonObject.optJSONObject("leftA"));
		rightL.loadPostion(jsonObject.optJSONObject("rightL"));
		leftL.loadPostion(jsonObject.optJSONObject("leftL"));
		
	}

	public void init() {
		/*rightL.calf.rotateTo(ydMath.degreesToRads(135));
		leftL.calf.rotateTo(ydMath.degreesToRads(135));
		rightA.forearm.rotateTo(ydMath.degreesToRads(0));
		leftA.forearm.rotateTo(ydMath.degreesToRads(0));
		
		rightL.thigh.rotateTo(ydMath.degreesToRads(135));
		leftL.thigh.rotateTo(ydMath.degreesToRads(45));
		rightA.arm.rotateTo(ydMath.degreesToRads(45));
		leftA.arm.rotateTo(ydMath.degreesToRads(225));
		
		//torso.torso.rotateTo(ydMath.degreesToRads(135));
		
		readjust();*/
		
	}

	public void setScale(float s){
		head.setScale(s);
		torso.setScale(s);
		rightA.setScale(s);
		leftA.setScale(s);
		
		readjust();
		
	}
	
}
